From 4ea6b4ceace8a83e41080d124511c78f2c78417c Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Thu, 12 Jul 2018 01:22:35 +0200 Subject: [PATCH] extensions/float: add ~ variants of conversions --- extensions/float.c | 219 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 193 insertions(+), 26 deletions(-) diff --git a/extensions/float.c b/extensions/float.c index 4012366..bce0de7 100644 --- a/extensions/float.c +++ b/extensions/float.c @@ -26,8 +26,10 @@ #include "extensions/util.h" #include "base/util.h" +static const Babl *trc_srgb = NULL; + static void -conv_rgbaF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src, +conv_rgbaF_linear_rgbAF_nonlinear (const Babl *conversion,unsigned char *src, unsigned char *dst, long samples) { @@ -49,10 +51,30 @@ conv_rgbaF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src, } static void -conv_rgbAF_linear_rgbAF_gamma (const Babl *conversion, - unsigned char *src, - unsigned char *dst, - long samples) +conv_rgbaF_linear_rgbAF_perceptual (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) +{ + float *fsrc = (float *) src; + float *fdst = (float *) dst; + int n = samples; + + while (n--) + { + float alpha = fsrc[3]; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; + *fdst++ = *fsrc++; + } +} + + +static void +conv_rgbAF_linear_rgbAF_nonlinear (const Babl *conversion, + unsigned char *src, + unsigned char *dst, + long samples) { const Babl *space = babl_conversion_get_destination_space (conversion); const Babl **trc = (void*)space->space.trc; @@ -91,9 +113,50 @@ conv_rgbAF_linear_rgbAF_gamma (const Babl *conversion, } static void -conv_rgbaF_linear_rgbaF_gamma (const Babl *conversion,unsigned char *src, - unsigned char *dst, - long samples) +conv_rgbAF_linear_rgbAF_perceptual (const Babl *conversion, + unsigned char *src, + unsigned char *dst, + long samples) +{ + + float *fsrc = (float *) src; + float *fdst = (float *) dst; + int n = samples; + + while (n--) + { + float alpha = fsrc[3]; + if (alpha < BABL_ALPHA_THRESHOLD) + { + *fdst++ = 0.0; + *fdst++ = 0.0; + *fdst++ = 0.0; + *fdst++ = 0.0; + fsrc+=4; + } + else if (alpha >= 1.0) + { + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha; + *fdst++ = *fsrc++; + } + else + { + float alpha_recip = 1.0 / alpha; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha; + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha; + *fdst++ = *fsrc++; + } + } +} + + +static void +conv_rgbaF_linear_rgbaF_nonlinear (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) { const Babl *space = babl_conversion_get_destination_space (conversion); const Babl **trc = (void*)space->space.trc; @@ -112,9 +175,28 @@ conv_rgbaF_linear_rgbaF_gamma (const Babl *conversion,unsigned char *src, } static void -conv_rgbF_linear_rgbF_gamma (const Babl *conversion,unsigned char *src, - unsigned char *dst, - long samples) +conv_rgbaF_linear_rgbaF_perceptual (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) +{ + float *fsrc = (float *) src; + float *fdst = (float *) dst; + int n = samples; + + while (n--) + { + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++); + *fdst++ = *fsrc++; + } +} + + +static void +conv_rgbF_linear_rgbF_nonlinear (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) { const Babl *space = babl_conversion_get_destination_space (conversion); const Babl **trc = (void*)space->space.trc; @@ -130,11 +212,28 @@ conv_rgbF_linear_rgbF_gamma (const Babl *conversion,unsigned char *src, } } +static void +conv_rgbF_linear_rgbF_perceptual (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) +{ + float *fsrc = (float *) src; + float *fdst = (float *) dst; + int n = samples; + + while (n--) + { + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++); + } +} + static void -conv_rgbaF_gamma_rgbaF_linear (const Babl *conversion,unsigned char *src, - unsigned char *dst, - long samples) +conv_rgbaF_nonlinear_rgbaF_linear (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) { const Babl *space = babl_conversion_get_destination_space (conversion); const Babl **trc = (void*)space->space.trc; @@ -152,9 +251,28 @@ conv_rgbaF_gamma_rgbaF_linear (const Babl *conversion,unsigned char *src, } static void -conv_rgbF_gamma_rgbF_linear (const Babl *conversion,unsigned char *src, - unsigned char *dst, - long samples) +conv_rgbaF_perceptual_rgbaF_linear (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) +{ + float *fsrc = (float *) src; + float *fdst = (float *) dst; + int n = samples; + + while (n--) + { + *fdst++ = babl_trc_to_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_to_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_to_linear (trc_srgb, *fsrc++); + *fdst++ = *fsrc++; + } +} + + +static void +conv_rgbF_nonlinear_rgbF_linear (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) { const Babl *space = babl_conversion_get_destination_space (conversion); const Babl **trc = (void*)space->space.trc; @@ -170,6 +288,24 @@ conv_rgbF_gamma_rgbF_linear (const Babl *conversion,unsigned char *src, } } +static void +conv_rgbF_perceptual_rgbF_linear (const Babl *conversion,unsigned char *src, + unsigned char *dst, + long samples) +{ + float *fsrc = (float *) src; + float *fdst = (float *) dst; + int n = samples; + + while (n--) + { + *fdst++ = babl_trc_to_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_to_linear (trc_srgb, *fsrc++); + *fdst++ = babl_trc_to_linear (trc_srgb, *fsrc++); + } +} + + #define o(src, dst) \ babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL) @@ -194,7 +330,7 @@ init (void) babl_component ("Ba"), babl_component ("A"), NULL); - const Babl *rgbaF_gamma = babl_format_new ( + const Babl *rgbaF_nonlinear = babl_format_new ( babl_model ("R'G'B'A"), babl_type ("float"), babl_component ("R'"), @@ -202,7 +338,15 @@ init (void) babl_component ("B'"), babl_component ("A"), NULL); - const Babl *rgbAF_gamma = babl_format_new ( + const Babl *rgbaF_perceptual = babl_format_new ( + babl_model ("R~G~B~A"), + babl_type ("float"), + babl_component ("R~"), + babl_component ("G~"), + babl_component ("B~"), + babl_component ("A"), + NULL); + const Babl *rgbAF_nonlinear = babl_format_new ( babl_model ("R'aG'aB'aA"), babl_type ("float"), babl_component ("R'a"), @@ -210,6 +354,14 @@ init (void) babl_component ("B'a"), babl_component ("A"), NULL); + const Babl *rgbAF_perceptual = babl_format_new ( + babl_model ("R~aG~aB~aA"), + babl_type ("float"), + babl_component ("R~a"), + babl_component ("G~a"), + babl_component ("B~a"), + babl_component ("A"), + NULL); const Babl *rgbF_linear = babl_format_new ( babl_model ("RGB"), babl_type ("float"), @@ -217,20 +369,35 @@ init (void) babl_component ("G"), babl_component ("B"), NULL); - const Babl *rgbF_gamma = babl_format_new ( + const Babl *rgbF_nonlinear = babl_format_new ( babl_model ("R'G'B'"), babl_type ("float"), babl_component ("R'"), babl_component ("G'"), babl_component ("B'"), NULL); + const Babl *rgbF_perceptual = babl_format_new ( + babl_model ("R~G~B~"), + babl_type ("float"), + babl_component ("R~"), + babl_component ("G~"), + babl_component ("B~"), + NULL); + trc_srgb = babl_trc("sRGB"); + + o (rgbAF_linear, rgbAF_nonlinear); + o (rgbaF_linear, rgbAF_nonlinear); + o (rgbaF_linear, rgbaF_nonlinear); + o (rgbaF_nonlinear, rgbaF_linear); + o (rgbF_linear, rgbF_nonlinear); + o (rgbF_nonlinear, rgbF_linear); - o (rgbAF_linear, rgbAF_gamma); - o (rgbaF_linear, rgbAF_gamma); - o (rgbaF_linear, rgbaF_gamma); - o (rgbaF_gamma, rgbaF_linear); - o (rgbF_linear, rgbF_gamma); - o (rgbF_gamma, rgbF_linear); + o (rgbAF_linear, rgbAF_perceptual); + o (rgbaF_linear, rgbAF_perceptual); + o (rgbaF_linear, rgbaF_perceptual); + o (rgbaF_perceptual, rgbaF_linear); + o (rgbF_linear, rgbF_perceptual); + o (rgbF_perceptual, rgbF_linear); return 0; } -- 2.30.2